package com.txy.springcloud.filter;

import com.txy.springcloud.client.TxyServiceUserFeignClient;
import com.txy.springcloud.model.RequestRecord;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpCookie;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 定义全局过滤器，会对所有路由生效
 */
@Slf4j
@Component  // 让容器扫描到，等同于注册了
public class AuthFilter implements GlobalFilter, Ordered {

    @Autowired
    private TxyServiceUserFeignClient userClient;

    @Value("${ip.forbid-strategy.x}")
    private int x;

    @Value("${ip.forbid-strategy.y}")
    private int y;

    private static Map<String, RequestRecord> map = new ConcurrentHashMap<String, RequestRecord>();

    // 模拟黑名单（实际可以去数据库或者redis中查询）
//    private static List<String> blackList = new ArrayList<>();
//
//    static {
//        blackList.add("0:0:0:0:0:0:0:1");  // 模拟本机地址
//    }

    /**
     * 过滤器核心方法
     * @param exchange 封装了request和response对象的上下文
     * @param chain 网关过滤器链（包含全局过滤器和单路由过滤器）
     * @return
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//        // 思路：获取客户端ip，判断是否在黑名单中，在的话就拒绝访问，不在的话就放行
//        // 从上下文中取出request和response对象
//        ServerHttpRequest request = exchange.getRequest();
//        ServerHttpResponse response = exchange.getResponse();
//
//        // 从request对象中获取客户端ip
//        String clientIp = request.getRemoteAddress().getHostString();
//        // 拿着clientIp去黑名单中查询，存在的话就决绝访问
//        if(blackList.contains(clientIp)) {
//            // 决绝访问，返回
//            response.setStatusCode(HttpStatus.UNAUTHORIZED); // 状态码
//            log.debug("=====>IP:" + clientIp + " 在黑名单中，将被拒绝访问！");
//            String data = "Request be denied!";
//            DataBuffer wrap = response.bufferFactory().wrap(data.getBytes());
//            return response.writeWith(Mono.just(wrap));
//        }
//
//        // 合法请求，放行，执行后续的过滤器
//        return chain.filter(exchange);
        MultiValueMap<String, HttpCookie> cookies = exchange.getRequest().getCookies();
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        System.out.println("收到请求:"+request.getURI());
        // 发送验证码频率限制
        if(request.getURI().toString().contains("/sendCode")) {
            String hostName = request.getRemoteAddress().getHostName();
            if(map.get(hostName)==null) {
                map.put(hostName, new RequestRecord(System.currentTimeMillis(),1));
            }else {
                RequestRecord requestRecord = map.get(hostName);
                requestRecord.setCount(requestRecord.getCount()+1);
                if(System.currentTimeMillis() - requestRecord.getStartTime()<=x*60*1000 && requestRecord.getCount()>=y) {
                    String data = "wait";
                    DataBuffer wrap = response.bufferFactory().wrap(data.getBytes());
                    return response.writeWith(Mono.just(wrap));
                }
                if(System.currentTimeMillis() - requestRecord.getStartTime()>x*60*1000) {
                    map.put(hostName, new RequestRecord(System.currentTimeMillis(),1));
                }
            }
        }
        // 登录校验
        if(!request.getURI().toString().contains("login") && !request.getURI().toString().contains("regist") && request.getQueryParams()!=null && request.getQueryParams().get("token")!=null) {
            String token = request.getQueryParams().get("token").get(0);
            String email = userClient.getEmailById(token);
            if(StringUtils.isBlank(email)) {
                String data = "denied";
                DataBuffer wrap = response.bufferFactory().wrap(data.getBytes());
                return response.writeWith(Mono.just(wrap));
            }
        }

//        for (String key : cookies.keySet()) {
//            if(key.equals("token")) {
//                if(cookies.get(key)!=null) {
//                    return chain.filter(exchange);
//                }
//            }
//        }
        return chain.filter(exchange);
//        String data = "Request be denied!";
//        DataBuffer wrap = response.bufferFactory().wrap(data.getBytes());
//        return response.writeWith(Mono.just(wrap));
    }


    /**
     * 返回值表示当前过滤器的顺序(优先级)，数值越小，优先级越高
     * @return
     */
    @Override
    public int getOrder() {
        return 0;
    }
}